//
// Created by 49647 on 2023/8/6.
//
#include <iostream>
#include <string>
#include <optional>

struct Format {
    bool GetInt(const std::string &key, int &val) const {
        printf("%s\n", __FUNCTION__);
        return false;
    }

    bool GetDouble(const std::string &key, double &val) const {
        printf("%s\n", __FUNCTION__);
        return false;
    }
};

template<typename T, typename ...args>
std::optional<T> GetValue(const Format &fmt, const std::string &key) {
    if constexpr(sizeof...(args) != 0) {
        std::optional<T> val = GetValue<T>(fmt, key);
        if (val) {
            return val;
        }
        return GetValue<args...>(fmt, key);
    }
    if constexpr(std::is_same_v<T, int>) {
        int v;
        if (fmt.GetInt(key, v)) {
            return v;
        }
    } else if constexpr(std::is_same_v<T, double>) {
        double v;
        if (fmt.GetDouble(key, v)) {
            return v;
        }
    }
    return std::nullopt;
}

int main() {
    Format fmt;
    GetValue<int>(fmt, "haha");
    GetValue<int, double>(fmt, "haha");
}